package com.icongyou.enterprise.talent_pool.service.impl;

import com.icongyou.enterprise.data_aggregation.entity.UserEntity;
import com.icongyou.enterprise.data_aggregation.service.DataAggregationService;
import com.icongyou.enterprise.talent_pool.entity.StudentAssignmentPerformanceEntity;
import com.icongyou.enterprise.talent_pool.entity.dto.TalentDemandDTO;
import com.icongyou.enterprise.talent_pool.entity.vo.*;
import com.icongyou.enterprise.talent_pool.mapper.AssignmentTagMapper;
import com.icongyou.enterprise.talent_pool.mapper.StudentAssignmentPerformanceMapper;
import com.icongyou.enterprise.talent_pool.service.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.test.util.ReflectionTestUtils;

import java.math.BigDecimal;
import java.util.*;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
class TalentPoolServiceImplTest {

    @Mock
    private TagProcessingService tagProcessingService;

    @Mock
    private AIModelService aiModelService;

    @Mock
    private AssignmentTagMapper assignmentTagMapper;

    @Mock
    private StudentAssignmentPerformanceMapper studentAssignmentPerformanceMapper;

    @Mock
    private StudentAssignmentPerformanceService studentAssignmentPerformanceService;

    @Mock
    private DataAggregationService dataAggregationService;

    @Mock
    private TalentSearchHistoryService talentSearchHistoryService;

    @Mock
    private CoreCompetenceService coreCompetenceService;

    // 使用 @Spy 来创建代理对象
    @Spy
    @InjectMocks
    private TalentPoolServiceImpl talentPoolService;

    private TalentDemandDTO demandDTO;
    private UserEntity userEntity;

    @BeforeEach
    void setUp() {
        demandDTO = new TalentDemandDTO();
        demandDTO.setUserId("user123");
        demandDTO.setDemandText("需要Java开发经验的学生");
        demandDTO.setPage(1);
        demandDTO.setSize(10);

        userEntity = new UserEntity();
        userEntity.setId("student123");
        userEntity.setRealName("张三");
        userEntity.setAvatar("avatar.jpg");
        userEntity.setMajor("计算机科学与技术");
        userEntity.setRanking(5);
        userEntity.setTenantId("tenant123");

        // 手动设置 selfProxy
        ReflectionTestUtils.setField(talentPoolService, "selfProxy", talentPoolService);
    }

    @Test
    void testMatchStudentsByDemand_EmptyDemandText() {
        // 准备
        demandDTO.setDemandText("");

        // 执行
        TalentMatchResultVO result = talentPoolService.matchStudentsByDemand(demandDTO);

        // 验证
        assertNotNull(result);
        assertTrue(result.getMatchedStudents().isEmpty());
        assertEquals(0, result.getTotalCount());
        assertFalse(result.getHasMore());
        assertNotNull(result.getSearchId());

        // 验证搜索历史没有保存
        verify(talentSearchHistoryService, never()).saveSearchHistory(anyString(), anyString());
    }

    @Test
    void testMatchStudentsByDemand_NoTagsExtracted() {
        // 准备
        when(aiModelService.analyzeDemandTags(anyString())).thenReturn(Collections.emptyList());

        // 执行
        TalentMatchResultVO result = talentPoolService.matchStudentsByDemand(demandDTO);

        // 验证
        assertNotNull(result);
        assertTrue(result.getMatchedStudents().isEmpty());
        assertEquals(0, result.getTotalCount());
        assertFalse(result.getHasMore());

        // 验证搜索历史保存被调用
        verify(talentSearchHistoryService).saveSearchHistory(eq("user123"), eq("需要Java开发经验的学生"));
    }

    @Test
    void testMatchStudentsByDemand_NoRelevantAssignments() {
        // 准备
        List<TagDemandAnalysisResult> tagResults = Arrays.asList(
                createTagAnalysisResult("Java", Arrays.asList("Spring", "JVM"))
        );

        when(aiModelService.analyzeDemandTags(anyString())).thenReturn(tagResults);
        when(tagProcessingService.processGeneratedTag(anyString(), anyList())).thenReturn("tag123");
        when(assignmentTagMapper.getAssignmentTagVOsByTagId(anyString())).thenReturn(Collections.emptyList());

        // 执行
        TalentMatchResultVO result = talentPoolService.matchStudentsByDemand(demandDTO);

        // 验证
        assertNotNull(result);
        assertTrue(result.getMatchedStudents().isEmpty());
        assertEquals(0, result.getTotalCount());
        assertFalse(result.getHasMore());
    }

    @Test
    void testMatchStudentsByDemand_SuccessfulMatch() {
        // 准备
        List<TagDemandAnalysisResult> tagResults = Arrays.asList(
                createTagAnalysisResult("Java", Arrays.asList("Spring", "JVM"))
        );

        AssignmentTagVO assignment1 = createAssignmentTagVO("assign1", "tag123",
                new BigDecimal("0.8"), new BigDecimal("1.0"), "Java项目");
        AssignmentTagVO assignment2 = createAssignmentTagVO("assign2", "tag123",
                new BigDecimal("0.6"), new BigDecimal("0.8"), "Spring项目");

        StudentAssignmentPerformanceEntity performance1 = new StudentAssignmentPerformanceEntity();
        performance1.setStudentId("student123");
        performance1.setAssignmentId("assign1");
        performance1.setPerformanceScore(85.0);

        StudentAssignmentPerformanceEntity performance2 = new StudentAssignmentPerformanceEntity();
        performance2.setStudentId("student123");
        performance2.setAssignmentId("assign2");
        performance2.setPerformanceScore(90.0);

        when(aiModelService.analyzeDemandTags(anyString())).thenReturn(tagResults);
        when(tagProcessingService.processGeneratedTag(anyString(), anyList())).thenReturn("tag123");
        when(assignmentTagMapper.getAssignmentTagVOsByTagId(anyString())).thenReturn(Arrays.asList(assignment1, assignment2));
        when(studentAssignmentPerformanceMapper.getPerformancesByAssignmentIds(anyList()))
                .thenReturn(Arrays.asList(performance1, performance2));
        when(dataAggregationService.getStudentById("student123")).thenReturn(userEntity);
        when(dataAggregationService.getTenantNameByUserId("student123")).thenReturn("清华大学");
        when(dataAggregationService.countStudentsByMajor("tenant123", "计算机科学与技术")).thenReturn(100);
        when(dataAggregationService.getCoreSubmission(anyString())).thenReturn(createCoreSubmissionVO());

        // 关键修复：模拟异步方法，避免实际调用
        doNothing().when(talentPoolService).generateCoreCompetenceLabelAsync(
                any(TalentDemandDTO.class), anyList(), anyString(), anyList(), anyMap());

        // 执行
        TalentMatchResultVO result = talentPoolService.matchStudentsByDemand(demandDTO);

        // 验证
        assertNotNull(result);
        assertFalse(result.getMatchedStudents().isEmpty());
        assertEquals(1, result.getTotalCount());
        assertEquals(1, result.getCurrentPage());
        assertEquals(10, result.getPageSize());
        assertFalse(result.getHasMore());
        assertNotNull(result.getSearchId());

        StudentTalentVO student = result.getMatchedStudents().get(0);
        assertEquals("student123", student.getStudentId());
        assertEquals("张三", student.getRealName());
        assertEquals("清华大学", student.getSchool());
        assertEquals("计算机科学与技术", student.getMajor());
        assertNotNull(student.getMatchScore());
        assertTrue(student.getMatchScore() > 0);

        // 验证异步方法被调用
        verify(talentPoolService).generateCoreCompetenceLabelAsync(
                eq(demandDTO), anyList(), anyString(), anyList(), anyMap());
    }

    @Test
    void testMatchStudentsByDemand_WithFilters() {
        // 准备
        demandDTO.setTeacherRecommended(true);
        demandDTO.setCoreTaskTop30(true);
        demandDTO.setHasHighPotential(true);

        List<TagDemandAnalysisResult> tagResults = Arrays.asList(
                createTagAnalysisResult("Java", Arrays.asList("Spring", "JVM"))
        );

        AssignmentTagVO assignment = createAssignmentTagVO("assign1", "tag123",
                new BigDecimal("0.8"), new BigDecimal("1.0"), "Java项目");

        StudentAssignmentPerformanceEntity performance = new StudentAssignmentPerformanceEntity();
        performance.setStudentId("student123");
        performance.setAssignmentId("assign1");
        performance.setPerformanceScore(85.0);

        when(aiModelService.analyzeDemandTags(anyString())).thenReturn(tagResults);
        when(tagProcessingService.processGeneratedTag(anyString(), anyList())).thenReturn("tag123");
        when(assignmentTagMapper.getAssignmentTagVOsByTagId(anyString())).thenReturn(Arrays.asList(assignment));
        when(studentAssignmentPerformanceMapper.getPerformancesByAssignmentIds(anyList()))
                .thenReturn(Arrays.asList(performance));

        // 设置筛选条件通过
        when(dataAggregationService.isTeacherRecommended("student123")).thenReturn(true);
        when(dataAggregationService.isCoreTaskTop30("student123")).thenReturn(true);
        when(dataAggregationService.hasHighPotentialSubmission("student123")).thenReturn(true);

        when(dataAggregationService.getStudentById("student123")).thenReturn(userEntity);
        when(dataAggregationService.getTenantNameByUserId("student123")).thenReturn("清华大学");
        when(dataAggregationService.countStudentsByMajor("tenant123", "计算机科学与技术")).thenReturn(100);
        when(dataAggregationService.getCoreSubmission(anyString())).thenReturn(createCoreSubmissionVO());

        // 关键修复：模拟异步方法
        doNothing().when(talentPoolService).generateCoreCompetenceLabelAsync(
                any(TalentDemandDTO.class), anyList(), anyString(), anyList(), anyMap());

        // 执行
        TalentMatchResultVO result = talentPoolService.matchStudentsByDemand(demandDTO);

        // 验证
        assertNotNull(result);
        assertEquals(1, result.getTotalCount());

        // 验证筛选服务被调用
        verify(dataAggregationService).isTeacherRecommended("student123");
        verify(dataAggregationService).isCoreTaskTop30("student123");
        verify(dataAggregationService).hasHighPotentialSubmission("student123");
    }

    @Test
    void testMatchStudentsByDemand_FilterFailed() {
        // 准备
        demandDTO.setTeacherRecommended(true);

        List<TagDemandAnalysisResult> tagResults = Arrays.asList(
                createTagAnalysisResult("Java", Arrays.asList("Spring", "JVM"))
        );

        AssignmentTagVO assignment = createAssignmentTagVO("assign1", "tag123",
                new BigDecimal("0.8"), new BigDecimal("1.0"), "Java项目");

        StudentAssignmentPerformanceEntity performance = new StudentAssignmentPerformanceEntity();
        performance.setStudentId("student123");
        performance.setAssignmentId("assign1");
        performance.setPerformanceScore(85.0);

        when(aiModelService.analyzeDemandTags(anyString())).thenReturn(tagResults);
        when(tagProcessingService.processGeneratedTag(anyString(), anyList())).thenReturn("tag123");
        when(assignmentTagMapper.getAssignmentTagVOsByTagId(anyString())).thenReturn(Arrays.asList(assignment));
        when(studentAssignmentPerformanceMapper.getPerformancesByAssignmentIds(anyList()))
                .thenReturn(Arrays.asList(performance));

        // 设置筛选条件不通过
        when(dataAggregationService.isTeacherRecommended("student123")).thenReturn(false);

        // 执行
        TalentMatchResultVO result = talentPoolService.matchStudentsByDemand(demandDTO);

        // 验证
        assertNotNull(result);
        assertEquals(0, result.getTotalCount());
        assertTrue(result.getMatchedStudents().isEmpty());
    }

    @Test
    void testExtractTagsFromDemand() {
        // 准备
        String demandText = "需要Java开发和Spring框架经验";
        List<TagDemandAnalysisResult> tagResults = Arrays.asList(
                createTagAnalysisResult("Java", Arrays.asList("JDK", "JVM")),
                createTagAnalysisResult("Spring", Arrays.asList("Spring Boot", "Spring MVC"))
        );

        when(aiModelService.analyzeDemandTags(demandText)).thenReturn(tagResults);
        when(tagProcessingService.processGeneratedTag(eq("Java"), anyList())).thenReturn("tag1");
        when(tagProcessingService.processGeneratedTag(eq("Spring"), anyList())).thenReturn("tag2");

        // 执行
        List<String> result = talentPoolService.extractTagsFromDemand(demandText);

        // 验证
        assertNotNull(result);
        assertEquals(2, result.size());
        assertTrue(result.contains("tag1"));
        assertTrue(result.contains("tag2"));

        verify(aiModelService).analyzeDemandTags(demandText);
        verify(tagProcessingService).processGeneratedTag(eq("Java"), anyList());
        verify(tagProcessingService).processGeneratedTag(eq("Spring"), anyList());
    }

    @Test
    void testExtractTagsFromDemand_EmptyText() {
        // 执行
        List<String> result = talentPoolService.extractTagsFromDemand("");

        // 验证
        assertNotNull(result);
        assertTrue(result.isEmpty());

        verify(aiModelService, never()).analyzeDemandTags(anyString());
        verify(tagProcessingService, never()).processGeneratedTag(anyString(), anyList());
    }

    @Test
    void testExtractTagsFromDemand_NullText() {
        // 执行
        List<String> result = talentPoolService.extractTagsFromDemand(null);

        // 验证
        assertNotNull(result);
        assertTrue(result.isEmpty());

        verify(aiModelService, never()).analyzeDemandTags(anyString());
        verify(tagProcessingService, never()).processGeneratedTag(anyString(), anyList());
    }

    @Test
    void testGetCoreCompetenceResult() {
        // 准备
        String searchId = "search_123";
        CoreCompetenceResultVO expectedResult = new CoreCompetenceResultVO();
        expectedResult.setSearchId(searchId);
        expectedResult.setStatus("COMPLETED");
        expectedResult.setMessage("生成完成");

        // 使用反射设置缓存
        Map<String, CoreCompetenceResultVO> cache = new HashMap<>();
        cache.put(searchId, expectedResult);
        ReflectionTestUtils.setField(talentPoolService, "competenceCache", cache);

        // 执行
        CoreCompetenceResultVO result = talentPoolService.getCoreCompetenceResult(searchId);

        // 验证
        assertNotNull(result);
        assertEquals(searchId, result.getSearchId());
        assertEquals("COMPLETED", result.getStatus());
        assertEquals("生成完成", result.getMessage());
    }

    @Test
    void testGetCoreCompetenceResult_NotFound() {
        // 执行
        CoreCompetenceResultVO result = talentPoolService.getCoreCompetenceResult("nonexistent");

        // 验证
        assertNotNull(result);
        assertEquals("nonexistent", result.getSearchId());
        assertEquals("NOT_FOUND", result.getStatus());
        assertEquals("未找到对应的搜索结果", result.getMessage());
    }

    @Test
    void testGenerateCoreCompetenceLabelAsync() throws Exception {
        // 准备
        TalentDemandDTO demand = new TalentDemandDTO();
        demand.setDemandText("需要Java开发经验");

        List<StudentTalentVO> students = Arrays.asList(createStudentTalentVO("student1"), createStudentTalentVO("student2"));
        String searchId = "search_123";

        List<AssignmentTagVO> assignments = Arrays.asList(
                createAssignmentTagVO("assign1", "tag1", new BigDecimal("0.8"), new BigDecimal("1.0"), "作业1")
        );

        Map<String, List<AssignmentPerformanceVO>> performances = new HashMap<>();
        performances.put("student1", Arrays.asList(createAssignmentPerformanceVO()));
        performances.put("student2", Arrays.asList(createAssignmentPerformanceVO()));

        when(coreCompetenceService.generateCoreCompetenceLabel(anyString(), anyString(), anyList(), anyList()))
                .thenReturn("Java开发能力强，具备良好的编码习惯");

        // 执行
        talentPoolService.generateCoreCompetenceLabelAsync(demand, students, searchId, assignments, performances);

        // 给异步方法一点时间执行
        Thread.sleep(200);

        // 验证
        verify(coreCompetenceService, times(2)).generateCoreCompetenceLabel(anyString(), anyString(), anyList(), anyList());

        // 验证缓存状态
        CoreCompetenceResultVO result = talentPoolService.getCoreCompetenceResult(searchId);
        assertNotNull(result);
        assertEquals("COMPLETED", result.getStatus());
        assertEquals(2, result.getCompetenceLabels().size());
    }

    // 辅助方法
    private TagDemandAnalysisResult createTagAnalysisResult(String tagName, List<String> similarTags) {
        TagDemandAnalysisResult result = new TagDemandAnalysisResult();
        result.setTagName(tagName);
        result.setSimilarTags(similarTags);
        return result;
    }

    private AssignmentTagVO createAssignmentTagVO(String assignmentId, String tagId,
                                                  BigDecimal relevance, BigDecimal weight, String name) {
        AssignmentTagVO vo = new AssignmentTagVO();
        vo.setAssignmentId(assignmentId);
        vo.setTagId(tagId);
        vo.setRelevance(relevance);
        vo.setAssignmentWeight(weight);
        vo.setAssignmentName(name);
        return vo;
    }

    private StudentTalentVO createStudentTalentVO(String studentId) {
        StudentTalentVO vo = new StudentTalentVO();
        vo.setStudentId(studentId);
        vo.setRealName("学生" + studentId);
        vo.setSchool("测试学校");
        vo.setMajor("计算机");
        return vo;
    }

    private AssignmentPerformanceVO createAssignmentPerformanceVO() {
        AssignmentPerformanceVO vo = new AssignmentPerformanceVO();
        vo.setAssignmentId("assign1");
        vo.setAssignmentName("作业1");
        vo.setPerformanceScore(new BigDecimal("85.0"));
        vo.setRelevance(new BigDecimal("0.8"));
        vo.setAssignmentWeight(new BigDecimal("1.0"));
        return vo;
    }

    private CoreSubmissionVO createCoreSubmissionVO() {
        CoreSubmissionVO vo = new CoreSubmissionVO();
        vo.setSubmissionId("sub123");
        vo.setAssignmentName("Java项目");
        vo.setTeacherComment("优秀");
        vo.setTaskDescription("完成一个Java Web项目");
        vo.setContentUrl("http://example.com/submission");
        vo.setScore(95.0);
        return vo;
    }
}